/*
============================================================================
 Name        : KeyWatcher.cpp
 Author      : DANG Zhengfa
 Version     :
 Copyright   : Zhengfa Company Limited
 Description : CKeyWatcher implementation
============================================================================
*/

#include "KeyWatcher.h"
#include "Log.h"
#include "KeyLocker.h"
#include "ScreenCapture.h"
#include "AudioRecorder.h"

CKeyWatcher::CKeyWatcher() : CActive(EPriorityStandard)// Standard priority
{

}

void CKeyWatcher::ConstructL()
{
	CActiveScheduler::Add(this);				// Add to scheduler

	// connect to window server
	User::LeaveIfError(iWS.Connect());

	// create a window group for the thread
	iWG = RWindowGroup(iWS);
	iWG.Construct((TUint32)&iWG, EFalse);
	iWG.SetOrdinalPosition(-1);
	iWG.EnableReceiptOfFocus(EFalse);

	// Construct screen
	iScreen = new(ELeave) CWsScreenDevice(iWS);
    iScreen->Construct();

	// hide this window group from the app switcher
	iWN = CApaWindowGroupName::NewL(iWS);
	iWN->SetHidden(ETrue);
	iWN->SetWindowGroupName(iWG);

	iHotkeyStar = 0;
	iHotkeyCross = 0;

	iLocker = NULL;
	iCapture = NULL;

	iRecorder = CAudioRecorder::NewL();
}

CKeyWatcher::~CKeyWatcher()
{
	Cancel(); // Cancel any request, if outstanding
	// Delete instance variables if any
	
	// cancel key capture
	if(iHotkeyStar) iWG.CancelCaptureKey(iHotkeyStar);
	if(iHotkeyCross) iWG.CancelCaptureKey(iHotkeyCross);
	if(iHotkeyZero) iWG.CancelCaptureKey(iHotkeyZero);
	
	// cleanup
	delete iScreen;
	delete iWN;
	iWG.Close();
	iWS.Close();

	delete iRecorder;
}

void CKeyWatcher::DoCancel()
{
	PrintString16(_L("Watcher DoCancel"));
	iWS.EventReadyCancel();
}

void CKeyWatcher::StartL()
{
	Cancel();						// Cancel any request, just to be sure

	PrintString16(_L("Watcher StartL"));
	CaptureKeyL();

	// listen for the key presses
	iWS.EventReady(&iStatus);
	SetActive();					// Tell scheduler a request is active
}

TInt CKeyWatcher::RunError(TInt aError)
{
	PrintString16(_L("CKeyWatcher::RunError"));
	PrintNumber(aError);
	return KErrNone;
}

void CKeyWatcher::RunL()
{
	PrintString16(_L("Watcher RunL()"));
	if ( iStatus.Int() == KErrNone ) 
	{
		TWsEvent event;
		iWS.GetEvent(event);

		TKeyEvent* aKeyEvent = event.Key();
		TInt ch = aKeyEvent->iCode;

		// do something with keypress
		switch(ch)
		{
		case '*':
			PrintString16(_L("'ABC+'*' is captured"));
			if(iLocker)
				iLocker->RunLockNow();
			break;
		case '#':
			PrintString16(_L("'ABC+'#' is captured"));
			CaptureScreenL();
			break;
		case '0':
			PrintString16(_L("'ABC+'0' is captured"));
			StartStopRecordL();
			break;

		default:
			// if not ours, then send to top window group			
			// note that this breaks key repeat :-(
			TInt wgid = iWS.GetFocusWindowGroup();
			iWS.SendEventToWindowGroup(wgid, event);
			break;
		}
	}

	// wait for next key event
	iWS.EventReady(&iStatus);
	SetActive();
}

void CKeyWatcher::CaptureKeyL(void)
{
	// capture '*'
	iHotkeyStar = iWG.CaptureKey('*', EModifierShift, EModifierShift);
	User::LeaveIfError(iHotkeyStar);

	// capture '#'
	iHotkeyCross = iWG.CaptureKey('#', EModifierShift, EModifierShift);
	User::LeaveIfError(iHotkeyCross);

	// capture '0'
	iHotkeyZero = iWG.CaptureKey('0', EModifierShift, EModifierShift);
	User::LeaveIfError(iHotkeyZero);
	
}

void CKeyWatcher::SetKeyLocker(CKeyLocker* aLocker)
{
	iLocker = aLocker;
}

TBool CKeyWatcher::CaptureScreenL(void)
{
	PrintString16(_L("CKeyWatcher::CaptureScreenL"));
	
	// If iLocker, iCapture are available, and keypad has not locked, capture screen
	if(iLocker && iCapture && !iLocker->IsKeyLocked())
	{
		PrintString16(_L("keypad not locked, capture screen"));
		iCapture->StartL();
	}
	return ETrue;	
}


TBool CKeyWatcher::StartStopRecordL(void)
{
	PrintString16(_L("CKeyWatcher::StartStopRecordL"));
	
	// If iLocker, iRecorder are available, and keypad has not locked, recording
	if(iRecorder && iLocker && !iLocker->IsKeyLocked())
	{
		if( iRecorder->IsRecording() )
		{
			PrintString16(_L("Recording is ongoing, Stop!"));
			iRecorder->StopRecord();
		}
		else
		{
			PrintString16(_L("Start Recording..."));
			// the argument is not used now, so set it to ETrue
			iRecorder->RecordMessageL(ETrue);
		}
	}
	return ETrue;	
}


void CKeyWatcher::SetScreenCapture(CScreenCapture* aCapture)
{
	iCapture = aCapture;
	if(iCapture)
	{
		iCapture->SetScreenDevice(iScreen);
	}

}
